package com.nulldev.util.web.nTubeExtensions.yt_chat_on_ntube;

import static com.nulldev.util.web.nTube.pages.Urlizer.decodeUrlizer;

import java.io.InputStream;
import java.util.Map;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.VariableAPI.ArrayUtils;
import com.nulldev.util.web.HttpClient.HttpClient;
import com.nulldev.util.web.HttpClient.HttpMethod;
import com.nulldev.util.web.HttpClient.HttpResponse;
import com.nulldev.util.web.HttpServer3.Response;
import com.nulldev.util.web.HttpServer3.legacyPages.v1.RequestType;
import com.nulldev.util.web.HttpServer3.pages.v3.HttpPage3;
import com.nulldev.util.web.URLUtils.URLQueryParser;
import com.nulldev.util.web.URLUtils.URLQueryParser.URLQueryParserOptions;
import com.nulldev.util.web.URLUtils.URLUtils;

public class YTChooseServerProxifier extends HttpPage3 {

	public YTChooseServerProxifier() {
		super("/proxy/chooseServer");
		super.setCachingMethod(CachingMethod.NO_CACHE);
		super.setCaptchaExclusion(true);
	}

	private static final String[] ALLOWED_DOMAINS = new String[]
		{ "signaler-pa.youtube.com" };

	@SuppressWarnings("resource")
	@Override
	public Response onRequest(final Request request) {
		if (!request.isType(RequestType.POST))
			return new Response(400).header("X-Reject-Reason", "INVALID_REQUEST_TYPE");
		if (!request.hasData())
			return new Response(400).header("X-Reject-Reason", "MISSING_POST");
		if (!request.hasHeader("Referer"))
			return new Response(400).header("X-Reject-Reason", "MISSING_REFERER");
		final Map<String, String> s = URLQueryParser.extract(request.url(), URLQueryParserOptions.PREFER_EXPERIMENTAL,
				(URLUtils.USE_URL_ACCEL_V2 ? null : URLQueryParserOptions.DISABLE_URL_ACCEL), URLQueryParserOptions.DISABLE_DECODING,
				URLQueryParserOptions.TREAT_URL_AS_QUERY);
		if (!s.containsKey("url") && !(s.containsKey("uzm") && s.containsKey("uzc"))) {
			return new Response(400).requestKeepAliveDisable(true).header("X-Reject-Reason", "MISSING_FIELDS");
		} else if (s.containsKey("url") && s.get("url").isEmpty()) {
			return new Response(400).requestKeepAliveDisable(true).header("X-Reject-Reason", "EMPTY_URL");
		}
		final String url = decodeUrlizer(request.url());
		if (!ArrayUtils.StringArrayUtils.cardedContains(ALLOWED_DOMAINS, URLUtils.getDomain(url))) {
			return new Response(401).requestKeepAliveDisable(true).header("X-Reject-Reason", "SECURITY_ERROR");
		}
		try {
			final String referer = request.header("Referer");
			final String trueReferer = "https://www.youtube.com/live_chat?" + referer.split("\\?")[1];
			final HttpResponse<InputStream> is = HttpClient.getStream().url(url).header("Content-Length", request.header("Content-Length"))
					.header("Content-Type", request.header("Content-Type", "application/json+protobuf")).header("Origin", "https://www.youtube.com")
					.header("Referer", trueReferer).create(HttpMethod.POST, request.getInputStream());
			return new Response(is.status(), is.data()).deferCompression(true).requestKeepAliveDisable(true);
		} catch (Exception e) {
			JVM.errorln(e);
			return fail(503);
		}
	}

}
